<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>小球碰撞</title>
    <style>
        * {
            margin: 0px;
            padding: 0px;
        }


        .box {
            position: relative;
            border: 1px solid #ff0000;
            overflow: hidden;
            margin: auto;
        }

        .ball {
            width: 40px;
            height: 40px;
            position: absolute;
            border-radius: 50%;
            text-align: center;
        }
    </style>
</head>

<body>
    <div class="box">
    </div>
</body>
<script>
    let width = 1300;
    let height = 800;

    // 获取到盒子dom对象
    let box = document.querySelector(".box");
    // 设置盒子的宽高
    box.style.width = width + "px";
    box.style.height = height + "px";

    // 获取在n和m之间的随机数值
    function getRandom(m, n) {
        return Math.floor(Math.random() * (n - m + 1) + m);
    }

    function getColor() {
        let r = getRandom(0, 255);
        let g = getRandom(0, 255);
        let b = getRandom(0, 255);
        // let和var的区别
        // return "rgb(" + r + "," + g + "," + b + ")";
        // ES6模板字符串写法：
        return `rgb(${r},${g},${b})`;
    }

    // for (let i = 0;i < 100;i ++) {
    //     console.log(getColor());
    // }

    // 创建保存小球的数组
    let balls = [];

    // 创建小球
    for (let i = 1 ; i <= 50; i++) {
        let div = document.createElement("div");
        div.style.backgroundColor = getColor();
        let ballSize = getRandom(20, 50);

        // 使用x和y变量存储偏移值（方便计算）
        div.x = getRandom(0, width - ballSize);
        div.y = getRandom(0, height - ballSize);

        // 随机的left偏移值
        div.style.left = div.x + "px";
        // 随机的top偏移值
        div.style.top = div.y + "px";

        div.style.width = ballSize + "px";
        div.style.height = ballSize + "px";
        div.style.lineHeight = ballSize + "px";
        div.innerText = i;

        // 设置x和y的运动标识量：标识出是x、y的哪个方向移动
        // 如果为true，那么往正方向移动，如果为false，往负方向移动
        div.xflag = Math.random() - 0.5 < 0;
        div.yflag = Math.random() - 0.5 < 0;

        // 随机一个移动速度
        div.speed = Math.random(4,10);

        // 给div添加class
        div.classList.add("ball");
        // 把创建的div放到容器中
        box.appendChild(div);

        // 创建的div放到数组中，集中管理。
        balls.push(div);
    }

    // 移动小球
    function moveBall() {
        for (let i = 0;i < balls.length;i ++) {
            let ball = balls[i];
            // 往右侧移动
            if (ball.xflag) {
                ball.x += ball.speed;
                // 往下移动
                if (ball.yflag) {
                    ball.y += ball.speed;
                    // 如果移动到下边界，掉头向上
                    if (ball.y >= height - ball.offsetHeight) {
                        ball.yflag = false;
                    }
                // 往上移动
                } else {
                    ball.y -= ball.speed;
                    // 如果移动到上边界，掉头向下
                    if (ball.y <= 0) {
                        ball.yflag = true;
                    }
                }
                // 如果移动到右侧边界，那么掉头往左
                if (ball.x >= width - ball.offsetWidth) {
                    ball.xflag = false;
                }
            // 往左侧移动
            } else {
                ball.x -= ball.speed;
                // 往下移动
                if (ball.yflag) {
                    ball.y += ball.speed;
                    // 如果移动到下边界，掉头向上
                    if (ball.y >= height - ball.offsetHeight) {
                        ball.yflag = false;
                    }
                // 往上移动
                } else {
                    ball.y -= ball.speed;
                    // 如果移动到上边界，掉头向下
                    if (ball.y <= 0) {
                        ball.yflag = true;
                    }
                }
                 // 如果移动到左侧边界，那么掉头往右
                 if (ball.x <= 0) {
                    ball.xflag = true;   
                }
            }
            ball.style.left = ball.x + "px";
            ball.style.top = ball.y + "px";
            crash(ball);
        }
    }

    function crash(ball) {
        for (let i = 0;i < balls.length;i ++) {
            let targetBall = balls[i];
            if (ball == targetBall) {
                continue;
            }
            // 判断是否碰撞
            if (Math.pow((ball.x - targetBall.x),2) + Math.pow((ball.y - targetBall.y),2) 
                <= Math.pow((ball.offsetWidth / 2 + targetBall.offsetWidth / 2),2)) {
                // 左侧碰撞
                if (ball.x < targetBall.x) {
                    ball.xflag = false;
                    // 上侧碰撞
                    if (ball.y < targetBall.y) {
                        ball.yflag = false;
                    // 下方碰撞
                    } else if (ball.y > targetBall.y) {
                        ball.yflag = true;
                    }
                    // 相等：不改变y方向（水平正面碰撞）
                    
                // 右侧碰撞
                } else if (ball.x > targetBall.x) {
                    ball.xflag = true
                    if (ball.y < targetBall.y) {
                        ball.yflag = false;
                    // 下方碰撞
                    } else if (ball.y > targetBall.y) {
                        ball.yflag = true;
                    }
                    // 相等：不改变y方向（水平正面碰撞）
                }
            }
        }
    }

    setInterval(moveBall,10);

</script>

</html>